package com.local.mychess;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.media.MediaPlayer;
import android.widget.Button;
import android.widget.Toast;
import android.app.AlertDialog;
import android.content.DialogInterface;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity implements ChessBoardView.OnMoveListener {
    private static final String TAG = "MainActivity";
    private static final int PERMISSION_REQUEST_CODE = 1;

    private Button backButton;
    private Button resetButton;
    private Button talkButton;
    private Button configButton;
    private ChessBoardView chessBoard;
    
    private boolean isLocalConnected = false;
    private VoiceService voiceService;


    private boolean isVoiceServiceBound = false;
    private MediaPlayer mediaPlayer;
    // 语音服务连接
    private ServiceConnection voiceServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG, "Voice service connected");
            VoiceService.LocalBinder binder = (VoiceService.LocalBinder) service;
            voiceService = binder.getService();
            isVoiceServiceBound = true;

            voiceService.setCallback(new VoiceService.Callback() {
                @Override
                public void onConnectSuccess() {
                    isLocalConnected = true;
                }

                @Override
                public void onConnectFail(String errorMsg) {
                    isLocalConnected = false;
                    Toast.makeText(MainActivity.this, "Connect failed: " + errorMsg, Toast.LENGTH_LONG).show();
                }

                @Override
                public void onDisconnect() {
                    isLocalConnected = false;
                }

                @Override
                public void onInitGame(String message) {
                    String[] array = message.split(":");
                    if (array.length < 4) {
                        return;
                    }
                    String[] board = array[3].split(",");
                    chessBoard.SetBoardAndRole(
                            Integer.parseInt(array[2]),
                            board,
                            Integer.parseInt(array[1]));
                }

                @Override
                public void onStepGame(String message) {
                    String[] array = message.split(":");
                    if (array.length < 6) {
                        return;
                    }
                    String[] toPlace = array[4].split(",");
                    String[] board = array[6].split(",");

                    chessBoard.SetBoard(
                            array[1], array[2],
                            Integer.parseInt(array[3]),
                            Integer.parseInt(toPlace[0]), //array[4]
                            Integer.parseInt(toPlace[1]),
                            Integer.parseInt(array[5]),
                            board); //array[6]
                }
            });

            voiceService.connectToServer();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG, "Voice service disconnected");
            voiceService = null;
            isVoiceServiceBound = false;
            isLocalConnected = false;
        }
    };

    // ChessBoardView.OnMoveListener 实现
    @Override
    public void onMove(int fromX, int fromY, int toX, int toY) {
        Log.d(TAG, String.format("move:%d,%d -> %d,%d", fromX, fromY, toX, toY));
        voiceService.sendMove(fromX, fromY, toX, toY);
    }

    @Override
    public void onWarn() {
        if (mediaPlayer != null && DeviceInfor.getCheck().equals("true")) {
            mediaPlayer.start();
        }
    }

    @Override
    public void onOutsizeFocus(int x) {
        if (x < 3) {
            backButton.requestFocus();
        } else if (x < 6) {
            talkButton.requestFocus();
        } else {
            resetButton.requestFocus();
        }
    }

    private ActivityResultLauncher<Intent> configActivityLauncher = registerForActivityResult(
            new ActivityResultContracts.StartActivityForResult(),
            result -> {
                // 检查结果是否成功且请求码匹配
                if (result.getResultCode() == RESULT_OK) {
                    chessBoard.invalidate();
                    chessBoard.requestFocus();
                }
            }
    );

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate: Activity created ");
        setContentView(R.layout.activity_main);
        DeviceInfor.loadConfig();
        backButton = findViewById(R.id.backButton);
        resetButton = findViewById(R.id.resetButton);
        talkButton = findViewById(R.id.talkButton);
        configButton = findViewById(R.id.configButton);
        chessBoard = findViewById(R.id.chessBoard);
        chessBoard.setOnMoveListener(this);
        mediaPlayer = MediaPlayer.create(this, R.raw.warn);

        checkPermissions();

        configButton.setOnClickListener(v -> {
                Intent intent = new Intent(MainActivity.this, ConfigActivity.class);
                configActivityLauncher.launch(intent);
            }
        );

        backButton.setOnClickListener(v -> {
            if (chessBoard.getPlayerRole() != 1 && chessBoard.getPlayerRole() != 2) {
                return;
            }
            // 创建对话框构建器
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("悔棋");
            builder.setMessage("确定要悔棋？");
            builder.setPositiveButton("是", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Log.d(TAG, "back");
                    voiceService.sendBackBoard();
                    dialog.dismiss(); // 关闭对话框
                }
            });

            // 设置"No"按钮及点击事件
            builder.setNegativeButton("否", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss(); // 关闭对话框
                }
            });

            // 设置对话框不可通过点击外部关闭
            builder.setCancelable(false);
            AlertDialog dialog = builder.create();
            dialog.show();
        });

        resetButton.setOnClickListener(v -> {
            if (chessBoard.getPlayerRole() != 1 && chessBoard.getPlayerRole() != 2) {
                return;
            }
            if (chessBoard.getCurrentTurn() > 2) {
                // 游戏已结束，不弹出对话框
                Log.d(TAG, "reset board");
                voiceService.sendResetBoard();
            } else {
                // 创建对话框构建器
                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setTitle("重置游戏");
                builder.setMessage("确定要重置游戏吗？");
                builder.setPositiveButton("是", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Log.d(TAG, "reset board");
                        voiceService.sendResetBoard();
                        dialog.dismiss(); // 关闭对话框
                    }
                });

                // 设置"No"按钮及点击事件
                builder.setNegativeButton("否", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss(); // 关闭对话框
                    }
                });

                // 设置对话框不可通过点击外部关闭
                builder.setCancelable(false);
                AlertDialog dialog = builder.create();
                dialog.show();
            }

        });

        talkButton.setOnTouchListener((v, event) -> {
            if (!isLocalConnected || voiceService == null) {
				unbindAndStopServices();
				startAndBindServices();
                return false;
            }

            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    Log.d(TAG, "Talk button pressed: Starting recording");
                    voiceService.startRecording();
                    talkButton.setText("说话中..");
                    return true;
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                    Log.d(TAG, "Talk button released: Stopping recording");
                    voiceService.stopRecording();
                    talkButton.setText("按下说话");
                    return true;
            }
            return false;
        });
		
		startAndBindServices();
        chessBoard.requestFocus();
        chessBoard.requestFocusFromTouch();
    }

    private void startAndBindServices() {
        // 启动并绑定语音服务
        Intent voiceIntent = new Intent(this, VoiceService.class);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            startForegroundService(voiceIntent);
        } else {
            startService(voiceIntent);
        }
        bindService(voiceIntent, voiceServiceConnection, BIND_AUTO_CREATE);
    }

    private void unbindAndStopServices() {
        if (isVoiceServiceBound) {
            unbindService(voiceServiceConnection);
            isVoiceServiceBound = false;
        }        
        stopService(new Intent(this, VoiceService.class));
    }

    private void checkPermissions() {
        Log.d(TAG, "checkPermissions: Checking required permissions");
        String[] permissions = {
                android.Manifest.permission.RECORD_AUDIO,
                android.Manifest.permission.INTERNET,
                android.Manifest.permission.MODIFY_AUDIO_SETTINGS
        };

        boolean needPermission = false;
        for (String permission : permissions) {
            if (ContextCompat.checkSelfPermission(this, permission)
                    != PackageManager.PERMISSION_GRANTED) {
                needPermission = true;
                Log.w(TAG, "checkPermissions: Missing permission: " + permission);
            }
        }

        if (needPermission) {
            ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST_CODE);
        } else {
            Log.i(TAG, "checkPermissions: All required permissions granted");
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions,
                                           int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == PERMISSION_REQUEST_CODE) {
            boolean allGranted = true;
            for (int i = 0; i < grantResults.length; i++) {
                if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                    allGranted = false;
                    break;
                }
            }

            if (!allGranted) {
                Toast.makeText(this, "Permissions are required to use the app",
                        Toast.LENGTH_LONG).show();
                finish();
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindAndStopServices();
    }



}